﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Reflection;
using Beaker.Injection;

namespace OpenCube.Nbt.Mapping.Converters
{
	public sealed class FlattenConverter
		: NbtMultiTypeConverter
	{
		private readonly INbtMapperFactory _mapperFactory;

		public FlattenConverter(INbtMapperFactory mapperFactory)
		{
			Contract.Requires<ArgumentNullException>(mapperFactory != null);
			_mapperFactory = mapperFactory;
		}

		protected override bool CanConvertToModel(IReadOnlyList<Type> sourceNbtTypes, Type targetModelType)
		{
			return targetModelType.GetTypeInfo().IsClass;
		}

		protected override bool CanConvertToNbt(Type sourceModel)
		{
			return sourceModel.GetTypeInfo().IsClass && sourceModel != typeof(string);
		}

		protected override object ConvertToModelValue(IConversionContext conversionContext, IReadOnlyList<object> nbtValue)
		{
			var property = conversionContext.MemberInfo as PropertyInfo;
			if (property != null)
			{
				INbtMapper mapper = _mapperFactory.Create(property.PropertyType);
				return mapper.MapToModel(conversionContext.NbtDictionary);
			}

			return null;
		}

		protected override IEnumerable<object> ConvertToNbtValue(IConversionContext conversionContext, object modelValue)
		{
			throw new NotImplementedException();
		}
	}
}
